﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace FACUI.BasicClass
{

    public class CfgNode
    {
        private string nodeName = "";
        private CfgNode parentNode = null;
        private readonly Dictionary<string, CfgNode> subCfgNodeDict = new Dictionary<string, CfgNode>();
        private readonly List<string> subCfgNodeList = new List<string>();
        public object Tag = null;
        private readonly Dictionary<string, string> valDict = new Dictionary<string, string>();

        public CfgNode(string nodeName)
        {
            this.nodeName = nodeName;
        }

        public bool AddSubNode(string nodeName)
        {
            if (this.subCfgNodeDict.ContainsKey(nodeName))
            {
                return false;
            }
            CfgNode node = new CfgNode(nodeName);
            this.subCfgNodeDict[nodeName] = node;
            this.subCfgNodeList.Add(nodeName);
            node.parentNode = this;
            return true;
        }

        public bool AddSubNode(CfgNode subNode)
        {
            if (subNode == null)
            {
                return false;
            }
            if (this.subCfgNodeDict.ContainsKey(subNode.NodeName))
            {
                return false;
            }
            this.subCfgNodeDict[subNode.NodeName] = subNode;
            this.subCfgNodeList.Add(subNode.NodeName);
            subNode.parentNode = this;
            return true;
        }

        public bool AddValue(string key, int intval)
        {
            if (string.IsNullOrEmpty(key))
            {
                return false;
            }
            this.valDict[key] = intval.ToString();
            return true;
        }

        public bool AddValue(string key, float floatval)
        {
            if (string.IsNullOrEmpty(key))
            {
                return false;
            }
            this.valDict[key] = floatval.ToString();
            return true;
        }

        public bool AddValue(string key, string val)
        {
            if (string.IsNullOrEmpty(key))
            {
                return false;
            }
            this.valDict[key] = val;
            return true;
        }

        public void ClearSubNodes()
        {
            this.subCfgNodeDict.Clear();
            this.subCfgNodeList.Clear();
        }

        public void ClearValue()
        {
            this.valDict.Clear();
        }

        public static bool FromCfgFile(CfgNode rootNode, string fileName)
        {
            IniFile file = new IniFile(fileName);
            if (!file.Load())
            {
                return false;
            }
            ICollection<string> allSectionName = file.GetAllSectionName();
            char[] separator = new char[] { '\\' };
            foreach (string str in allSectionName)
            {
                string[] strArray = str.Split(separator);
                if ((strArray != null) && (strArray.Length != 0))
                {
                    CfgNode node = rootNode;
                    for (int i = 0; i < strArray.Length; i++)
                    {
                        string nodeName = strArray[i];
                        node.AddSubNode(nodeName);
                        node = node.subCfgNodeDict[nodeName];
                    }
                    foreach (string str2 in file.GetSectionItemName(str))
                    {
                        node.valDict[str2] = file.GetString(str, str2);
                    }
                }
            }
            return true;
        }

        public CfgNode GetNodeDirect(string nodePath)
        {
            return this.GetNodeDirect(nodePath, false);
        }

        public CfgNode GetNodeDirect(string nodePath, bool createIfNotExist)
        {
            if (string.IsNullOrEmpty(nodePath))
            {
                return null;
            }
            string[] strArray = nodePath.Split(new char[] { '\\' });
            if ((strArray == null) || (strArray.Length == 0))
            {
                return null;
            }
            CfgNode subNode = this;
            for (int i = 0; i < strArray.Length; i++)
            {
                subNode = subNode.GetSubNode(strArray[i], createIfNotExist);
                if (subNode == null)
                {
                    return null;
                }
            }
            return subNode;
        }

        public CfgNode GetParentNode()
        {
            return this.parentNode;
        }

        public CfgNode GetSubNode(string subNodeName)
        {
            if (this.subCfgNodeDict.ContainsKey(subNodeName))
            {
                return this.subCfgNodeDict[subNodeName];
            }
            return null;
        }

        public CfgNode GetSubNode(string subNodeName, bool createIfNotExist)
        {
            CfgNode node = null;
            if (this.subCfgNodeDict.ContainsKey(subNodeName))
            {
                node = this.subCfgNodeDict[subNodeName];
            }
            if ((node == null) && createIfNotExist)
            {
                node = new CfgNode(subNodeName)
                {
                    parentNode = this
                };
                this.subCfgNodeDict.Add(subNodeName, node);
                this.subCfgNodeList.Add(subNodeName);
            }
            return node;
        }

        public ICollection<CfgNode> GetSubNodeList()
        {
            return this.subCfgNodeDict.Values;
        }

        public static List<CfgNode> GetSubNodes(CfgNode cfgNode, string strSubNodes)
        {
            List<CfgNode> list = new List<CfgNode>();
            if ((cfgNode != null) && !string.IsNullOrEmpty(strSubNodes))
            {
                string[] strArray = Util.SplitTrimString(strSubNodes);
                if ((strArray == null) || (strArray.Length == 0))
                {
                    return list;
                }
                foreach (string str in strArray)
                {
                    CfgNode subNode = cfgNode.GetSubNode(str);
                    if (subNode != null)
                    {
                        list.Add(subNode);
                    }
                }
            }
            return list;
        }

        public Dictionary<string, string> GetValDict()
        {
            return this.valDict;
        }

        public string GetValue(string key)
        {
            return this.GetValue(key, "");
        }

        public string GetValue(int key, string defval)
        {
            return this.GetValue(key.ToString(), "");
        }

        public string GetValue(string key, string defval)
        {
            if (string.IsNullOrEmpty(key))
            {
                return "";
            }
            if (this.valDict.ContainsKey(key))
            {
                return this.valDict[key];
            }
            return defval;
        }

        public float GetValueFloat(string key)
        {
            string str;
            if (string.IsNullOrEmpty(key))
            {
                return 0f;
            }
            if (this.valDict.ContainsKey(key))
            {
                str = this.valDict[key];
            }
            else
            {
                str = "-1";
            }
            try
            {
                return float.Parse(str);
            }
            catch (Exception exception)
            {
                return -1f;
            }
        }

        public int GetValueInt(string key)
        {
            return this.GetValueInt(key, -1);
        }

        public int GetValueInt(int iKey, int defval)
        {
            return this.GetValueInt(iKey.ToString(), defval);
        }

        public int GetValueInt(string key, int defval)
        {
            if (string.IsNullOrEmpty(key))
            {
                return 0;
            }
            if (this.valDict.ContainsKey(key))
            {
                string s = this.valDict[key];
                try
                {
                    return int.Parse(s);
                }
                catch (Exception exception)
                {
                    return -1;
                }
            }
            return defval;
        }

        public bool Load()
        {
            Debug.Assert(!string.IsNullOrEmpty(this.NodeCfgFileName), "节点对应存储文件名称为空！");
            IniFile file = new IniFile(this.NodeCfgFileName);
            return FromCfgFile(this, this.NodeCfgFileName);
        }

        public void Merge(CfgNode cfgNode, bool bRecursive, int depth)
        {
            if (cfgNode != null)
            {
                foreach (KeyValuePair<string, string> pair in cfgNode.valDict)
                {
                    this.valDict[pair.Key] = pair.Value;
                }
                if (bRecursive)
                {
                    if (depth > 0)
                    {
                        depth--;
                    }
                    if (depth != 0)
                    {
                        foreach (CfgNode node in cfgNode.subCfgNodeDict.Values)
                        {
                            this.AddSubNode(node.NodeName);
                            this.subCfgNodeDict[node.NodeName].Merge(node, bRecursive, depth - 1);
                        }
                    }
                }
            }
        }

        public bool RemoveSubNode(string subNodeName)
        {
            this.subCfgNodeList.Remove(subNodeName);
            return this.subCfgNodeDict.Remove(subNodeName);
        }

        public bool RemoveSubNode(CfgNode subNode)
        {
            if (subNode == null)
            {
                return false;
            }
            subNode.parentNode = null;
            this.subCfgNodeList.Remove(subNode.NodeName);
            return this.subCfgNodeDict.Remove(subNode.NodeName);
        }

        public bool RemoveValue(string key)
        {
            return this.valDict.Remove(key);
        }

        public bool Save()
        {
            Debug.Assert(!string.IsNullOrEmpty(this.NodeCfgFileName), "节点对应存储文件名称为空！");
            IniFile iniFile = new IniFile(this.NodeCfgFileName);
            SaveSubNodesToCfgFile(iniFile, this);
            iniFile.Save();
            return true;
        }

        public bool Save(string filePath)
        {
            Debug.Assert(!string.IsNullOrEmpty(filePath), "节点对应存储文件名称为空！");
            IniFile iniFile = new IniFile(filePath);
            SaveSubNodesToCfgFile(iniFile, this);
            iniFile.Save();
            return true;
        }

        public bool Save(string filePath, CfgNode cfgNode)
        {
            IniFile iniFile = new IniFile(filePath);
            SaveSheBeiToCfgFile(iniFile, cfgNode.GetSubNode("设备信息"), "");
            iniFile.Save();
            return true;
        }

        public static void SaveSheBeiToCfgFile(IniFile iniFile, CfgNode cfgNode, string parentSect)
        {
            string section = (parentSect == "") ? cfgNode.NodeName : (parentSect + @"\" + cfgNode.NodeName);
            if (cfgNode.valDict.Count > 0)
            {
                foreach (KeyValuePair<string, string> pair in cfgNode.valDict)
                {
                    if (!section.Contains(@"\设备"))
                    {
                        iniFile.WriteString(section, pair.Key, pair.Value);
                    }
                }
            }
            else if (cfgNode.subCfgNodeDict.Count == 0)
            {
                iniFile.WriteString(section, "", "");
            }
            foreach (CfgNode node in cfgNode.subCfgNodeDict.Values)
            {
                SaveSheBeiToCfgFile(iniFile, node, section);
            }
        }

        public static void SaveSubNodesToCfgFile(IniFile iniFile, CfgNode cfgNode)
        {
            foreach (CfgNode node in cfgNode.subCfgNodeDict.Values)
            {
                SaveToCfgFile(iniFile, node, "");
            }
        }

        public static void SaveToCfgFile(IniFile iniFile, CfgNode cfgNode, string parentSect)
        {
            string section = (parentSect == "") ? cfgNode.NodeName : (parentSect + @"\" + cfgNode.NodeName);
            if (cfgNode.valDict.Count > 0)
            {
                foreach (KeyValuePair<string, string> pair in cfgNode.valDict)
                {
                    iniFile.WriteString(section, pair.Key, pair.Value);
                }
            }
            else if (cfgNode.subCfgNodeDict.Count == 0)
            {
                iniFile.WriteString(section, "", "");
            }
            foreach (CfgNode node in cfgNode.subCfgNodeDict.Values)
            {
                SaveToCfgFile(iniFile, node, section);
            }
        }

        public void SetNodename(string name)
        {
            if (this.parentNode == null)
            {
                this.nodeName = name;
            }
            else if (!this.parentNode.subCfgNodeDict.ContainsKey(name))
            {
                for (int i = 0; i < this.parentNode.subCfgNodeList.Count; i++)
                {
                    if (this.parentNode.subCfgNodeList[i] == this.nodeName)
                    {
                        this.parentNode.subCfgNodeList[i] = name;
                        break;
                    }
                }
                this.nodeName = name;
                Dictionary<string, CfgNode> dictionary = new Dictionary<string, CfgNode>();
                foreach (CfgNode node in this.parentNode.subCfgNodeDict.Values)
                {
                    dictionary.Add(node.nodeName, node);
                }
                this.parentNode.subCfgNodeDict.Clear();
                foreach (string str in dictionary.Keys)
                {
                    this.parentNode.subCfgNodeDict[str] = dictionary[str];
                }
            }
        }

        public void SetSubnodeName(string name)
        {
            int count = this.subCfgNodeList.Count;
            int num2 = 1;
            Dictionary<string, CfgNode> dictionary = new Dictionary<string, CfgNode>();
            foreach (string str in this.subCfgNodeList)
            {
                this.subCfgNodeDict[str].nodeName = name + num2.ToString();
                dictionary.Add(name + num2.ToString(), this.subCfgNodeDict[str]);
                num2++;
            }
            this.subCfgNodeList.Clear();
            for (num2 = 1; num2 <= count; num2++)
            {
                this.subCfgNodeList.Add(name + num2.ToString());
            }
            this.subCfgNodeDict.Clear();
            foreach (string str in this.subCfgNodeList)
            {
                this.subCfgNodeDict[str] = dictionary[str];
            }
        }

        public override string ToString()
        {
            return this.nodeName;
        }

        public string this[string key]
        {
            get
            {
                return this.GetValue(key);
            }
            set
            {
                this.valDict[key] = value;
            }
        }

        public string NodeCfgFileName { get; set; }

        public string NodeName
        {
            get
            {
                return this.nodeName;
            }
            set
            {
                this.nodeName = value;
            }
        }
    }
}

